package scau.gsmg.misp.service.impl;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.apache.struts2.ServletActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;

import com.opensymphony.xwork2.inject.util.Strings;


import scau.gsmg.misp.dao.IUserDAO;
import scau.gsmg.misp.service.ILoginService;
import scau.gsmg.misp.utils.IncorrectCaptchaException;
import scau.gsmg.misp.utils.ShiroUtil;
import scau.gsmg.misp.utils.UsernamePasswordCaptchaToken;
import scau.gsmg.misp.vo.Permission;
import scau.gsmg.misp.vo.Role;
import scau.gsmg.misp.vo.User;
import scau.gsmg.misp.vo.UserRole;

//import com.google.common.base.Objects;

/*import edu.scau.misp.core.utils.security.Encodes;
import edu.scau.misp.system.entity.Permission;
import edu.scau.misp.system.entity.User;
import edu.scau.misp.system.entity.UserRole;
import edu.scau.misp.system.utils.CaptchaException;
import edu.scau.misp.system.utils.UsernamePasswordCaptchaToken;
*/
/**
 * 用户登录授权service(shrioRealm)
 * 
 */
@Service
//@DependsOn({"userDao"})
public class UserRealmService extends AuthorizingRealm {

	 private ILoginService loginService;
	 @Override
	    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
	        //获取当前用户
	       // User user=ShiroUtil.getUserByPrincipalsRealmName(principals,getName());
		  
		 System.out.println("%%%%%%%%%%%%%%%%");
		     User u=(User)principals.getPrimaryPrincipal();;
		     System.out.println(u.getName());
		    // Role role ;
		     List<Role> list= loginService.searchRole(u);	
	        //创建授权信息实体
	        SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
	        //获取用户角色并添加到授权信息实体
	      //赋予角色
			for(Role role:list){
				System.out.println(role.getName());
				authorizationInfo.addRole(role.getRoleCode());
				System.out.println("role.getId()  "+role.getId());
				List<Permission> listPermission=loginService.findPermissions(role.getId());
				if(listPermission!=null&&listPermission.size()!=0){
					for(int i=0;i<listPermission.size();i++){
						authorizationInfo.addStringPermission(listPermission.get(i).getPermCode());
						System.out.println(listPermission.get(i).getPermCode()+"permissionnnnn");
					}
				}
				/*for(int i=0;i<listPermission.size();i++){
					authorizationInfo.addStringPermission(listPermission.get(i).getPermCode());
					System.out.println(listPermission.get(i).getPermCode()+"permissionnnnn");
				}*/
				
				System.out.println("~ ~ ~ ~  ");
			}
	        //String[] roles={"custom","user"};//换成数据库直接查询list
	      //  authorizationInfo.addRoles(Arrays.asList(roles));
	        //获取用户权限并添加到授权信息实体
	       // String[] permissions={"create","delete","update","user:edit"};
	       // System.out.println("String[] permissions={};");
	       // authorizationInfo.addStringPermissions(Arrays.asList(permissions));
	        //此处处理完成可以放入一些额外的通用信息到session中
	        return authorizationInfo;
	    }

	 @Override
	    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

		 System.out.println("%%%%%%%%%%%%%%%%eeeeeeeeeeeeee");
		UsernamePasswordCaptchaToken passwordToken = (UsernamePasswordCaptchaToken) token; 
		 System.out.println("%%%%%%%%%%%%%%%%"+passwordToken.getUsername());
		User user=new User();
		
		 
		 
		String username = (String)passwordToken.getPrincipal();  //得到用户名  
        String password = new String((char[])passwordToken.getCredentials()); //得到密码  
        String captcha =(String)passwordToken.getCaptcha(); 
        System.out.println(username+" "+password+" "+captcha);
		// UsernamePasswordCaptchaToken passwordToken=(UsernamePasswordCaptchaToken)token;
	        
	       
	      
        System.out.println("!!!!!!!!!!!!!!!!!success"+passwordToken.getUsername());
        if(passwordToken.getUsername()!=null){
        	System.out.println("!!!!!!!!!!!!!!!!!success"+Integer.valueOf(passwordToken.getUsername()));
 	        user.setId(Integer.valueOf(passwordToken.getUsername()));
 	     
        }
        if(doCaptchaValidate(passwordToken)){
        	  user=loginService.login(user);
    	      //  System.out.println("||||||win"+user.getPassword());
    	        //一些前置处理，判断帐号是否存在，帐号是否锁定
    	        if (user != null) {
    				//设置用户session
    				Session session =SecurityUtils.getSubject().getSession();
    				 System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
    				session.setAttribute("user", user);
    				 System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
    				return new SimpleAuthenticationInfo(user,user.getPassword(), getName());
    			}
        }
		return null;
//	        user = loginService.login(passwordToken.getUsername());
	       // user.setPassword(new String(passwordToken.getPassword()));
	      
	       /* System.out.println("RRRRRR");
	        if(user==null){
	        	System.out.println("null");
	            throw new UnknownAccountException();//没找到帐号;
	        }else{
	        	//设置用户session
				Session session =SecurityUtils.getSubject().getSession();
				session.setAttribute("user", user);
	        }
	        	else {
	        }
	        	System.out.println(passwordToken.getPassword()+user.getPassword());
	        	if(passwordToken.getUsername()!=null){
	        		if(!(passwordToken.getPassword()).equals(user.getPassword())){
	        			System.out.println("password");
	        			throw new IncorrectCredentialsException();
	        		}
	        	}
	        }
	        System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
	        System.out.println("||||||win"+user.getName());
	        System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&11");
	       SimpleAuthenticationInfo authenticationInfo=
	               new SimpleAuthenticationInfo(user,user.getPassword(),getName());
	       System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&333");
	        return authenticationInfo;*/
	    }

		/**
		 * 验证码校验
		 * @param token
		 * @return boolean
		 */
		protected boolean doCaptchaValidate(UsernamePasswordCaptchaToken token)
		{
			String captcha = (String) SecurityUtils.getSubject().getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
			System.out.println(captcha+token.getCaptcha());
			if (captcha != null &&!captcha.equalsIgnoreCase(token.getCaptcha())){
				throw new IncorrectCaptchaException("验证码错误！");
			}
			return true;
		}
	 
	    /**
	     * 获取认证信息在缓存中的键值
	     * 此方法可以自定义认证信息在缓存中的键值，可以使用唯一标识和信息对应的方式
	     * 此处的principals为此类中doGetAuthenticationInfo方法设置的principal，
	     * 如果此realm前面还有realm，将有多个principal
	     *
	     * @param principals 凭证
	     * @return key
	     */
	    protected Object getAuthorizationCacheKey(PrincipalCollection principals) {
	        return super.getAuthorizationCacheKey(principals);
	    }

	    /**
	     * 此方法登录时不会调用，且使用缓存时才调用此方法，默认使用传入的token键值作为缓存key，
	     * 此方法在登出时调用，返回值必须和
	     * {@link #getAuthenticationCacheKey(org.apache.shiro.authc.AuthenticationToken)}相同
	     * <p/>
	     * {@link org.apache.shiro.realm.AuthenticatingRealm#getAuthenticationCacheKey(org.apache.shiro.subject.PrincipalCollection)}
	     *
	     * @param principals
	     * @return
	     */
	    @Override
	    protected Object getAuthenticationCacheKey(PrincipalCollection principals) {
	        return super.getAuthenticationCacheKey(principals);
	    }

	    /**
	     * 认证缓存key，登录时调用，默认使用token值，使用缓存时才调用此方法
	     * {@link org.apache.shiro.realm.AuthenticatingRealm#getAuthenticationCacheKey(org.apache.shiro.authc.AuthenticationToken)}
	     *
	     * @param token token
	     * @return key
	     */
	    protected Object getAuthenticationCacheKey(AuthenticationToken token) {
	        return super.getAuthenticationCacheKey(token);
	    }
		public ILoginService getLoginService() {
			return loginService;
		}
		@Resource
		public void setLoginService(ILoginService loginService) {
			this.loginService = loginService;
		}

	   
 
}
